package com.rongzhe.house.house.service;

import com.alibaba.fastjson.JSON;
import com.rongzhe.house.common.utils.DateUtil;
import com.rongzhe.house.common.utils.PageUtils;
import com.rongzhe.house.dictionary.enums.DictEnums;
import com.rongzhe.house.dictionary.service.DictService;
import com.rongzhe.house.house.criteria.HouseCriteria;
import com.rongzhe.house.house.dao.*;
import com.rongzhe.house.house.entity.*;
import com.rongzhe.house.house.enums.UserCollectionType;
import com.rongzhe.house.order.criteria.ItemCriteria;
import com.rongzhe.house.order.dao.ItemMapper;
import com.rongzhe.house.order.entity.Item;
import com.rongzhe.house.order.entity.ItemExt;
import com.rongzhe.house.order.enums.ItemBizType;
import com.rongzhe.house.user.dao.UserBaseMapper;
import com.rongzhe.house.user.entity.UserBase;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.elasticsearch.action.search.MultiSearchResponse;
import org.elasticsearch.action.search.SearchRequestBuilder;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.client.Client;
import org.elasticsearch.common.geo.GeoPoint;
import org.elasticsearch.common.unit.DistanceUnit;
import org.elasticsearch.index.query.BoolQueryBuilder;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.search.SearchHit;
import org.elasticsearch.search.sort.SortOrder;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import java.util.*;

/**
 * Created by hggxg on 2017/11/18.
 */
@Slf4j
@Service
public class HouseServiceImpl implements HouseService {


    public static final String ES_HOUSE_INDEX = "house";

    @Autowired
    private HouseBaseMapper houseBaseMapper;

    @Autowired
    private HouseRoomLiveInfoMapper houseRoomLiveInfoMapper;


    @Autowired
    private HouseRentPaymentConfigMapper houseRentPaymentConfigMapper;

    @Autowired
    private HouseImageMapper houseImageMapper;

    @Autowired
    private HouseTrafficMapper houseTrafficMapper;


    @Autowired
    private UserCollectionMapper userCollectionMapper;

    @Autowired
    private HouseDelegationApplyMapper houseDelegationApplyMapper;

    @Autowired
    private LifeServiceMapper lifeServiceMapper;


    @Autowired
    private Client client;

    @Autowired
    private ItemMapper itemMapper;

    @Autowired
    private DictService dictService;


    @Autowired
    private UserBaseMapper userBaseMapper;


    @Override
    public List<HouseOverview> getExcellentHouse(String cityId) {

        return houseBaseMapper.selectExcellentHouse(cityId);

    }

    @Override
    public Map<String, List<HouseOverview>> getExcellentHouseOther(String provinceId) {
        //整租
        List<HouseOverview> entireRentHouse = getResult(provinceId, true, false);
        //合租
        List<HouseOverview> notEntireRentHouse = getResult(provinceId, false, false);
        //直租
        List<HouseOverview> ownerRentHouse = getResult(provinceId, false, true);

        Map<String, List<HouseOverview>> result = new HashMap<>();
        result.put("entireRentHouse", entireRentHouse);
        result.put("notEntireRentHouse", notEntireRentHouse);
        result.put("ownerRentHouse", ownerRentHouse);
        return result;
    }

    /**
     * 获取不同类型的房子 默认查询五条记录
     *
     * @param cityId
     * @param isEntireRent
     * @param ownerRent
     * @return
     */
    private List<HouseOverview> getResult(String cityId, boolean isEntireRent, boolean ownerRent) {
        HouseCriteria houseCriteria = new HouseCriteria();
        houseCriteria.setEntireRent(isEntireRent);
        houseCriteria.setOwnerRent(ownerRent);
        houseCriteria.setCityId(cityId);
        // 默认查询五条
        houseCriteria.setPageSize(5);
        PageUtils.initPageParam(houseCriteria);
        List<HouseOverview> excellentHouse = houseBaseMapper.getExcellentHouse(houseCriteria);
        return excellentHouse;
    }

    @Override
    public List<HouseOverview> queryHouseByCriteria(HouseCriteria houseCriteria) {


        int offset = houseCriteria.getPageSize() * (houseCriteria.getCurrentPage() - 1);

        int limit = houseCriteria.getPageSize();


        BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery();
        boolQueryBuilder.must(QueryBuilders.termQuery("cityId", houseCriteria.getCityId() == null ? "5001" : houseCriteria.getCityId()));


        if (!CollectionUtils.isEmpty(houseCriteria.getRoomNumList())) {
            boolQueryBuilder.must(QueryBuilders.termsQuery("roomNum", houseCriteria.getRoomNumList()));
        }

        //公寓
        if (houseCriteria.isApartment()) {
            //如果是公寓
            boolQueryBuilder.must(QueryBuilders.termsQuery("apartment", "1"));
        }

//        boolQueryBuilder.must(QueryBuilders.termsQuery("rentStatus", "1"));

        if (!StringUtils.isEmpty(houseCriteria.getCountyId())) {
            boolQueryBuilder.must(QueryBuilders.termQuery("countyId", houseCriteria.getCountyId()));
        }

        if (!StringUtils.isEmpty(houseCriteria.getKeyword())) {
            boolQueryBuilder.must(QueryBuilders.multiMatchQuery(houseCriteria.getKeyword(), "name", "countyName", "route", "station"));
        }

        if (houseCriteria.getEntireRent() != null) {
            boolQueryBuilder.must(QueryBuilders.termQuery("isEntireRent", houseCriteria.getEntireRent()));
        }

        if (houseCriteria.getOwnerRent() != null) {
            boolQueryBuilder.must(QueryBuilders.termQuery("isOwnerRent", houseCriteria.getOwnerRent()));
        }

        if (houseCriteria.getRentStart() != null && houseCriteria.getRentEnd() != null) {
            boolQueryBuilder.must(QueryBuilders.rangeQuery("rent").gte(houseCriteria.getRentStart().doubleValue()).lte(houseCriteria.getRentEnd().doubleValue()));
        }


        if (houseCriteria.getEnterTime() != null) {
            boolQueryBuilder.must(QueryBuilders.rangeQuery("enterTime").gte(DateUtil.getFormatDateTime(houseCriteria.getEnterTime(), "yyyy-MM-dd")));
        }

        if (houseCriteria.getRentStart() != null && houseCriteria.getRentEnd() == null) {
            boolQueryBuilder.must(QueryBuilders.rangeQuery("rent").gte(houseCriteria.getRentStart().doubleValue()));
        }

        if (houseCriteria.getRentStart() == null && houseCriteria.getRentEnd() != null) {
            boolQueryBuilder.must(QueryBuilders.rangeQuery("rent").lte(houseCriteria.getRentEnd().doubleValue()));
        }

        if (houseCriteria.getRoute() != null) {
            boolQueryBuilder
                    .must(QueryBuilders.termsQuery("railList", houseCriteria.getRoute()));
        }

        if (houseCriteria.getStation() != null) {
            boolQueryBuilder
                    .must(QueryBuilders.termsQuery("railStationList", houseCriteria.getStation()));
        }

        if (houseCriteria.getRoomNum() != null) {
            boolQueryBuilder.must(QueryBuilders.termQuery("roomNum", houseCriteria.getRoomNum()));
        }


        if (houseCriteria.isFindRound()) {

            GeoPoint geoPoint = new GeoPoint();
            geoPoint.reset(houseCriteria.getLat(), houseCriteria.getLon());
            boolQueryBuilder.must(QueryBuilders.geoDistanceQuery("location").point(geoPoint).distance(2, DistanceUnit.KILOMETERS));
        }

        SearchRequestBuilder srb1 = client
                .prepareSearch(ES_HOUSE_INDEX).setQuery(boolQueryBuilder).setFrom(offset).setSize(houseCriteria.getPageSize())
                .addSort("insertTime", SortOrder.DESC);

        MultiSearchResponse sr = client.prepareMultiSearch()
                .add(srb1)
                .get();

        List<Long> ids = new ArrayList<>();
        for (MultiSearchResponse.Item item : sr.getResponses()) {

            SearchResponse response = item.getResponse();


            if (response == null) continue;
            SearchHit[] searchHits = response.getHits().getHits();
            if (searchHits != null && searchHits.length != 0) {
                for (int i = 0; i < searchHits.length; i++) {
                    ids.add(Long.parseLong(searchHits[i].getId()));
                }
            }
        }
        if (CollectionUtils.isEmpty(ids)) {
            return null;
        }
        System.out.println(JSON.toJSON(ids));
        List<HouseOverview> houseOverviews = houseBaseMapper.selectHouseByIds(ids);

        return houseOverviews;

    }

    @Override
    public HouseDetail detail(Integer houseId, Integer userId) {

        HouseDetail houseDetail = houseBaseMapper.selectDetailById(houseId);

        if (houseDetail != null) {
            houseDetail.setHouseRoomLiveInfoList(houseRoomLiveInfoMapper.selectRoomInfoListByHouseId(houseId));

            houseDetail.setHouseImageList(houseImageMapper.selectListByHouseId(houseId));

            houseDetail.setHouseTrafficList(houseTrafficMapper.selectListByHouseId(houseId));

            houseDetail.setHouseTags(houseBaseMapper.selectHouseTagById(houseId));

            ItemCriteria itemCriteria = new ItemCriteria();
            itemCriteria.setBizId(houseId);
            itemCriteria.setBizType(ItemBizType.HOUSE_RENT_PAY.getType());

            List<Item> items = itemMapper.selectByItemCriteria(itemCriteria);


            List<String> codes = new ArrayList<>();
            if (!CollectionUtils.isEmpty(items)) {
                for (Item item : items) {
                    ItemExt itemExt = JSON.parseObject(item.getExt(), ItemExt.class);
                    codes.add(itemExt.getRentOption());
                }
            }

            codes.sort(new RentOptionComparator());

            Map<String, String> map = dictService.getMapByParentCode(DictEnums.House_Rent_Pay_Type.getCode());

            List<String> paymentList = new ArrayList<>();

            for (String code : codes) {
                paymentList.add(map.get(code));
            }

            houseDetail.setRentPaymentList(paymentList);

            UserBase userBase = userBaseMapper.selectByPrimaryKey(houseDetail.getManagerUid());

            if (userBase != null) {
                userBase.setPassword(null);
            }
            //管家信息
            houseDetail.setManagerInfo(userBase);

        }

        if (userId != null) {
            UserCollection userCollection = userCollectionMapper
                    .selectByUidAndTypeAndBizIdForUpdate(userId, UserCollectionType.HOUSE.getType(), houseId);

            houseDetail.setCanCollection(userCollection == null);
        } else {
            houseDetail.setCanCollection(true);
        }


        //查询客租日期信息 TODO
        houseDetail.setContractStart(new Date());

        //
        Calendar calendar
                = Calendar.getInstance();
        calendar.add(Calendar.YEAR, 1);

        houseDetail.setContractEnd(calendar.getTime());


        return houseDetail;
    }

    @Override
    public List<HouseRentPaymentConfig> getHouseRentPayConfigListByHouseId(Integer houseId) {


        return houseRentPaymentConfigMapper.selectHouseRentPayConfigListByHouseId(houseId);

    }

    @Override
    public boolean collection(Integer houseId, Integer userId) {


        UserCollection userCollectionSelect = userCollectionMapper
                .selectByUidAndTypeAndBizIdForUpdate(userId, UserCollectionType.HOUSE.getType(), houseId);


        if (userCollectionSelect == null) {
            //没有收藏
            UserCollection userCollection = new UserCollection();
            userCollection.setUid(userId);
            userCollection.setBizId(houseId);
            userCollection.setInsertUid(userId);
            userCollection.setType((byte) UserCollectionType.HOUSE.getType());
            userCollectionMapper.insertSelective(userCollection);
        } else {
            //已经收藏了，取消收藏
            userCollectionMapper.deleteByPrimaryKey(userCollectionSelect.getId());
        }


        return false;
    }

    @Override
    public List<HouseOverview> collectionGet(Integer userId, Integer pageSize, Integer currentPage) {


        int total = houseBaseMapper.countCollectionHouseByUid(userId);


        if (total == 0) {
            return null;
        }

        int offset = pageSize * (currentPage - 1);

        int limit = pageSize;

        List<HouseOverview> houseOverviews = houseBaseMapper.selectCollectionHouseByUid(userId, limit, offset);


        return houseOverviews;

    }

    @Override
    public boolean delegationApply(HouseDelegationApply delegationApply) {


        //魔数
        delegationApply.setFlag("1");

        delegationApply.setInsertTime(new Date());

        int result = houseDelegationApplyMapper.insertSelective(delegationApply);

        return result == 1;
    }

    @Override
    public List<LifeService> getLifeService(Integer type) {

        return lifeServiceMapper.selectByType(type);

    }

}
